/*
 * @Author: 生俊甫 1758142861@qq.com
 * @Date: 2025-01-19 17:29:52
 * @LastEditors: 生俊甫 1758142861@qq.com
 * @LastEditTime: 2025-01-25 20:13:56
 * @FilePath: /sjf/weChat_project/test_to_there/framework/etcd_test/server.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <etcd/Client.hpp>
#include <etcd/KeepAlive.hpp>
#include <etcd/Response.hpp>
#include <etcd/Watcher.hpp>
#include <thread>
#include "../spdlog_test/logger.hpp"

/**
 * 主要的就是
 * 1.实例化客户端对象
 * 2.获取键值对信息
 * 3.对该进行进行监控并进行对应的回调处理
 */
DEFINE_bool(run_mode,false,"运行模式(true表示发布模式,false表示调试模式)");
DEFINE_string(log_file,"","发布模式下,指定的日志输出文件名");
DEFINE_int32(log_level,0,"发布模式下,指定的日志输出等级");

void callback(const etcd::Response& resp)
{
    if(resp.is_ok() == false)
    {
        LOG_ERROR("收到一个错误的事件通知: {}",resp.error_message());
        return;
    }
    for(auto const& ev : resp.events())
    {
        if(ev.event_type() == etcd::Event::EventType::PUT)
        {
            LOG_DEBUG("服务发生变化");
            LOG_DEBUG("当前的值: {}-{}",ev.kv().key(),ev.kv().as_string());
            LOG_DEBUG("原来的值: {}-{}",ev.prev_kv().key(),ev.prev_kv().as_string());
            // std::cout << "服务发生变化\n";
            // std::cout << "当前的值: " << ev.kv().key() << "-" << ev.kv().as_string() << std::endl;
            // std::cout << "原来的值: " << ev.prev_kv().key() << "-" << ev.prev_kv().as_string() << std::endl;
        }else if(ev.event_type() == etcd::Event::EventType::DELETE_)
        {
            LOG_DEBUG("服务信息下线被删除");
            LOG_DEBUG("当前的值: {}-{}",ev.kv().key(),ev.kv().as_string());
            LOG_DEBUG("原来的值: {}-{}",ev.prev_kv().key(),ev.prev_kv().as_string());
            // std::cout << "服务信息下线被删除\n";
            // std::cout << "当前的值: " << ev.kv().key() << "-" << ev.kv().as_string() << std::endl;
            // std::cout << "原来的值: " << ev.prev_kv().key() << "-" << ev.prev_kv().as_string() << std::endl;
        }
    }
}

int main(int argc,char* argv[])
{
    google::ParseCommandLineFlags(&argc,&argv,true);
    init_logger(FLAGS_run_mode,FLAGS_log_file,FLAGS_log_level);

    std::string etcd_host = "http://127.0.0.1:2379";
    //实例化客户端对象
    etcd::Client client(etcd_host);
    //获取指定的键值对信息
    auto resp = client.ls("/service").get();
    if(resp.is_ok() == false)
    {
        LOG_ERROR("获取键值对信息出差: {}",resp.error_message());
        return -1;
    }
    int sz = resp.keys().size();
    for(int i = 0; i < sz; i++)
    {
        std::cout << resp.value(i).as_string() << "可以提供:" << resp.key(i) << "服务" << std::endl;
    }
    //实例化一个键值对事件监控对象
    auto watcher = etcd::Watcher(client,"/service",callback,true);
    watcher.Wait();
    return 0;
}